{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import tensorflow as tf\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "(train_images, train_labels), (test_images, test_labels) = tf.keras.datasets.mnist.load_data()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_images = train_images.reshape(60000,28,28,1)\n",
    "test_images = test_images.reshape(10000,28,28,1)\n",
    "#增加维度，用于卷积操作"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_images = train_images / 255\n",
    "test_images = test_images/ 255"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_labels = np.array(pd.get_dummies(train_labels))\n",
    "test_labels = np.array(pd.get_dummies(test_labels))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "model = tf.keras.Sequential()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.add(tf.keras.layers.Conv2D(filters = 6,kernel_size = (5,5),input_shape=(28,28,1),padding = 'same',activation = \"sigmoid\"))\n",
    "model.add(tf.keras.layers.AveragePooling2D(pool_size = (2, 2)))\n",
    "model.add(tf.keras.layers.Conv2D(filters = 16,kernel_size = (5,5),activation = \"sigmoid\"))\n",
    "model.add(tf.keras.layers.AveragePooling2D(pool_size = (2, 2)))\n",
    "model.add(tf.keras.layers.Conv2D(filters = 120,kernel_size = (5,5),activation = \"sigmoid\"))\n",
    "model.add(tf.keras.layers.Flatten())\n",
    "model.add(tf.keras.layers.Dense(84, activation='sigmoid'))\n",
    "model.add(tf.keras.layers.Dense(10, activation='softmax'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_3\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "conv2d_9 (Conv2D)            (None, 28, 28, 6)         156       \n",
      "_________________________________________________________________\n",
      "average_pooling2d_6 (Average (None, 14, 14, 6)         0         \n",
      "_________________________________________________________________\n",
      "conv2d_10 (Conv2D)           (None, 10, 10, 16)        2416      \n",
      "_________________________________________________________________\n",
      "average_pooling2d_7 (Average (None, 5, 5, 16)          0         \n",
      "_________________________________________________________________\n",
      "conv2d_11 (Conv2D)           (None, 1, 1, 120)         48120     \n",
      "_________________________________________________________________\n",
      "flatten_2 (Flatten)          (None, 120)               0         \n",
      "_________________________________________________________________\n",
      "dense_9 (Dense)              (None, 84)                10164     \n",
      "_________________________________________________________________\n",
      "dense_10 (Dense)             (None, 10)                850       \n",
      "=================================================================\n",
      "Total params: 61,706\n",
      "Trainable params: 61,706\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['acc'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/10\n",
      "1875/1875 [==============================] - 37s 19ms/step - loss: 1.4908 - acc: 0.4763 - val_loss: 0.2464 - val_acc: 0.9286\n",
      "Epoch 2/10\n",
      "1875/1875 [==============================] - 31s 17ms/step - loss: 0.2135 - acc: 0.9357 - val_loss: 0.1389 - val_acc: 0.9558\n",
      "Epoch 3/10\n",
      "1875/1875 [==============================] - 31s 17ms/step - loss: 0.1353 - acc: 0.9581 - val_loss: 0.0920 - val_acc: 0.9710\n",
      "Epoch 4/10\n",
      "1875/1875 [==============================] - 30s 16ms/step - loss: 0.0919 - acc: 0.9715 - val_loss: 0.0752 - val_acc: 0.9771\n",
      "Epoch 5/10\n",
      "1875/1875 [==============================] - 28s 15ms/step - loss: 0.0774 - acc: 0.9759 - val_loss: 0.0612 - val_acc: 0.9813\n",
      "Epoch 6/10\n",
      "1875/1875 [==============================] - 28s 15ms/step - loss: 0.0611 - acc: 0.9820 - val_loss: 0.0628 - val_acc: 0.9799\n",
      "Epoch 7/10\n",
      "1875/1875 [==============================] - 28s 15ms/step - loss: 0.0533 - acc: 0.9840 - val_loss: 0.0476 - val_acc: 0.9865\n",
      "Epoch 8/10\n",
      "1875/1875 [==============================] - 29s 15ms/step - loss: 0.0469 - acc: 0.9856 - val_loss: 0.0488 - val_acc: 0.9840\n",
      "Epoch 9/10\n",
      "1875/1875 [==============================] - 31s 16ms/step - loss: 0.0461 - acc: 0.9847 - val_loss: 0.0459 - val_acc: 0.9842\n",
      "Epoch 10/10\n",
      "1875/1875 [==============================] - 28s 15ms/step - loss: 0.0366 - acc: 0.9879 - val_loss: 0.0457 - val_acc: 0.9840\n"
     ]
    }
   ],
   "source": [
    "history = model.fit(train_images,train_labels,epochs = 10,validation_data=(test_images,test_labels))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "313/313 [==============================] - 2s 6ms/step - loss: 0.0457 - acc: 0.9840\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0.0456596240401268, 0.984000027179718]"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.evaluate(test_images,test_labels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 保存模型\n",
    "model.save('mnist.h5')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
